#include "MeleeEnemy.h"

MeleeEnemy::MeleeEnemy()
	: Enemy()
	, mCurrentHealth (5)
	, mMaxSpeed (200.0f)
	, mDestination (200.0f, 200.0f)
	, mMeleeDelay (3.0f)
	, mAlertDistance (500.0f)
{
}

MeleeEnemy::~MeleeEnemy()
{
}

void MeleeEnemy::Load()
{
	mSprite.Add("hoodlum1.png");
	mSprite.Add("hoodlum2.png");
	mCurrentHealth.Load();
	mMeleeAttack.Load("skateboard");
	mDeathSound.Load("skaterdeath.wav");
}

void MeleeEnemy::Unload()
{
	mSprite.Unload();
	mCurrentHealth.Unload();
	mMeleeAttack.Unload();
	mDeathSound.Unload();
}

void MeleeEnemy::Update(float deltaTime, Map& map, Character& character)
{
	if(mActive)
	{
		mSprite.Update(deltaTime);
		mPosition += mVelocity * deltaTime;

		if(Distance(character.GetPosition(), mPosition) <= mAlertDistance)
			Seek(deltaTime, character);
		else
			mVelocity = SVector2(0.0f, 0.0f);

		MeleeAttack(deltaTime, character);
		mMeleeAttack.Update(deltaTime);

		mCurrentHealth.Update(deltaTime, mPosition);
		if(!mCurrentHealth.IsAlive())
			Kill();
	}
}

void MeleeEnemy::Render(const SVector2& viewOffset)
{
	if(mActive)
	{
		int width = mSprite.GetWidth();
		int height = mSprite.GetHeight();

		SVector2 offset(width * 0.5f, height * 0.5f);
		SVector2 renderPosition = mPosition - offset - viewOffset;

		mSprite.SetPosition(renderPosition);

		if(mVelocity.x > 0.0f)
			mSprite.SetFlipH(true);
		else
			mSprite.SetFlipH(false);

		mSprite.Render();

		mMeleeAttack.Render(viewOffset);
		mCurrentHealth.Render(viewOffset);
		//Graphics_DebugCircle(GetBoundingCircle());
	}
}

void MeleeEnemy::Spawn(const SVector2& pos)
{
	mPosition = pos;
	mVelocity = SVector2(0.0f, 200.0f);
	mActive = true;
	mSprite.Play(4.0f, true);
}

void MeleeEnemy::Kill()
{
	mActive = false;
	mSprite.Stop();
	mSprite.Reset();
	mDeathSound.Play(false);
}

SRect MeleeEnemy::GetBoundingBox() const
{
	SRect boundingBox;

	boundingBox.min.x = mPosition.x - 32.0f;
	boundingBox.max.x = mPosition.x + 32.0f;
	boundingBox.min.y = mPosition.y - 60.0f;
	boundingBox.max.y = mPosition.y + 60.0f;

	return boundingBox;
}

void MeleeEnemy::Seek(float deltaTime, Character& character)
{
	mDestination = character.GetPosition();
	SVector2 positionToDestination = mDestination - mPosition;
	SVector2 desiredVelocity = Normalize(positionToDestination) * mMaxSpeed;
	
	SVector2 force = desiredVelocity - mVelocity;
	SVector2 acceleration = force / 1.0f;
	mVelocity += acceleration * deltaTime;
	mVelocity.Truncate(mMaxSpeed);
}

void MeleeEnemy::MeleeAttack(float deltaTime, Character& character)
{
	mMeleeDelay -= deltaTime;
	if(mMeleeDelay <= 0)
	{
		SCircle mCircle = GetBoundingCircle();
		SCircle cCircle = character.GetBoundingCircle();

		float xDiff = cCircle.center.x - mCircle.center.x;
		float yDiff = cCircle.center.y - cCircle.center.y;

		float distance = sqrt(xDiff * xDiff + yDiff * yDiff);
		float radii = cCircle.radius + mCircle.radius;

		if(distance <= radii)
		{
				SVector2 pos = mPosition;
				bool facingLeft = false;
				if(mVelocity.x < 0.0f)
				{
					pos.x -= 30.0f;
					facingLeft = true;
				}
				else if(mVelocity.x >= 0.0f)
				{
					pos.x += 25.0f;
					facingLeft = false;
				}

				mMeleeAttack.Attack(pos, facingLeft);
				if(!character.IsShielded())
					character.mCurrentHealth.TakeDamage(1);
		}
		mMeleeDelay = 3.0f;
	}
}